package logger

import (
	"sync"
	"sync/atomic"
)

type Level int

const (
	LevelNone Level = iota
	LevelTrace
	LevelDebug
	LevelInfo
	LevelWarn
	LevelError
	LevelFatal
	LevelIgnore
)

var LevelStrings = []string{
	"NON",
	"TRC",
	"DBG",
	"INF",
	"WRN",
	"ERR",
	"FAT",
	"IGN",
}

func (lv Level) String() string {
	return LevelStrings[lv]
}

const MaxSwitchModule int32 = 256

// bitset模型的模块日志开关
// 模块号请用户自行定义, 从0开始, 最大值为MaxSwitchModule-1
type Switch struct {
	modules []uint64
	lock    sync.Mutex
}

func makeSwitch() *Switch {
	return &Switch{
		modules: make([]uint64, MaxSwitchModule),
	}
}

func (s *Switch) Set(module int32, innerMask uint64) {
	if module < 0 || module >= MaxSwitchModule {
		return
	}
	s.lock.Lock()
	defer s.lock.Unlock()
	s.modules[module] |= innerMask
}

func (s *Switch) Unset(module int32, innerMask uint64) {
	if module < 0 || module >= MaxSwitchModule {
		return
	}
	s.lock.Lock()
	defer s.lock.Unlock()
	s.modules[module] &= ^innerMask
}

func (s *Switch) Check(module int32, innerMask uint64) bool {
	if module < 0 || module >= MaxSwitchModule {
		return false
	}
	return (s.modules[module] & innerMask) != 0
}

func (s *Switch) Get(module int32) uint64 {
	if module < 0 || module >= MaxSwitchModule {
		return 0
	}
	return s.modules[module]
}

// 模块日志开关检查器, 只可配置一个模块. 用于在运行时动态调整日志开关.
// 如果想要配置多个模块, 请分开使用多个Logger
type SwitchChecker struct {
	module int32
	mask   uint64
}

func NewSwitchChecker(module int32, mask uint64) *SwitchChecker {
	return &SwitchChecker{
		module: module,
		mask:   mask,
	}
}

func (sc *SwitchChecker) Clone() *SwitchChecker {
	return &SwitchChecker{
		module: atomic.LoadInt32(&sc.module),
		mask:   atomic.LoadUint64(&sc.mask),
	}
}

func (sc *SwitchChecker) Check(s *Switch) bool {
	return s.Check(sc.module, sc.mask)
}
